﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using OpenTK.Input;

enum FileFormat { obj=1, ms3d=2, dae=3}

namespace Reconstructor
{

   
    public partial class MainWindow : Form
    {
        private bool glLoaded;
        public MainWindow()
        {
            InitializeComponent();
            MainController.Instance.RegisterMainVindow(this);
        }

        public GLControl GLControl
        {
            get { return gl_control; }
        }


        private void on_glLoad(object sender, EventArgs e)
        {
            glLoaded = true;
            GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.Texture2D);
            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.NormalArray);
            GL.EnableClientState(ArrayCap.TextureCoordArray);
        }
        const float rotation_speed = 10.0f;
        float angle=0F;
        OpenTK.Vector3d up = new OpenTK.Vector3d(0.0, 1.0, 0.0);
        OpenTK.Vector3d viewDirection = new OpenTK.Vector3d(1.0, 1.0, 1.0);
        double viewDist = 3.0;
        private void on_glPaint(object sender, PaintEventArgs e)
        {
            if (!glLoaded || !MainController.Instance.draw) return;
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
           // AddLights();
            Matrix4d camera = Matrix4d.LookAt(OpenTK.Vector3d.Multiply(viewDirection, viewDist),
                                                OpenTK.Vector3d.Zero, up);
            GL.LoadMatrix(ref camera);

           
            GL.Rotate(angle, 0.0f, 1.0f, 0.0f);
           
            MainController.Instance.drawer.DrawBuffer();
          
            
           gl_control.SwapBuffers();

        }

        private void AddLights()
        {
            float[] mat_specular = { 1.0f, 1.0f, 1.0f, 1.0f };
            float[] mat_shininess = { 50.0f };
            float[] light_position = { 10.0f, 10.0f, 10.0f, 10.0f };
            float[] light_ambient = { 0.5f, 0.5f, 0.5f, 1.0f };

            //GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            //GL.ShadeModel(ShadingModel.Smooth);

            //GL.Material(MaterialFace.Front, MaterialParameter.Specular, mat_specular);
            //GL.Material(MaterialFace.Front, MaterialParameter.Shininess, mat_shininess);
            GL.Light(LightName.Light0, LightParameter.Position, light_position);
            GL.Light(LightName.Light0, LightParameter.Ambient, light_ambient);
            GL.Light(LightName.Light0, LightParameter.Diffuse, mat_specular);

            GL.Enable(EnableCap.Lighting);
            GL.Enable(EnableCap.Light0);
            GL.Enable(EnableCap.ColorMaterial);
        }



        private void on_glResize(object sender, EventArgs e)
        {
            GL.Viewport(gl_control.ClientRectangle.X, gl_control.ClientRectangle.Y, gl_control.ClientRectangle.Width, gl_control.ClientRectangle.Height);

            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);
            gl_control.Invalidate();
        }

        private void saveOBJToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void loadOBJToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openObjDialog.ShowDialog();
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            MainController.Instance.LoadMeshDataFromFile(openObjDialog.OpenFile(),(FileFormat)openObjDialog.FilterIndex);
        }

        private void OnLoadText(object sender, EventArgs e)
        {
            openTextureDialog.ShowDialog();
        }

        private void OnTextureOk(object sender, CancelEventArgs e)
        {
            MainController.Instance.LoadTexture(openTextureDialog.OpenFile());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MainController.Instance.StartDrawing();
        }

        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.A)
            {
                angle -= rotation_speed;
                gl_control.Invalidate();
                DB.Log("A Pressed");
            }
            else if (e.KeyCode == Keys.D)
            {
                angle += rotation_speed;
                gl_control.Invalidate();
                DB.Log("D Pressed");
            }
        }

        private void KeyDownEvent(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.A)
            {
                angle -= rotation_speed;
                gl_control.Invalidate();
                DB.Log("A Pressed");
            }
            else if (e.KeyCode == Keys.D)
            {
                angle += rotation_speed;
                gl_control.Invalidate();
                DB.Log("D Pressed");
            }
            else if (e.KeyCode == Keys.W)
            {
                viewDist -= 0.1F;
                gl_control.Invalidate();
                DB.Log("W Pressed");
            }
            else if (e.KeyCode == Keys.S)
            {
                viewDist += 0.1F;
                gl_control.Invalidate();
                DB.Log("S Pressed");
            }
       
        }

        
    }
}
